package com.xiangban.xiangbanmall.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xiangban.xiangbanmall.config.IdCardParameterConfig;
import com.xiangban.xiangbanmall.exception.BizException;
import com.xiangban.xiangbanmall.fegin.UserServiceFeign;
import com.xiangban.xiangbanmall.model.res.ApiResult;
import com.xiangban.xiangbanmall.model.res.ApiResultCode;
import lombok.extern.slf4j.Slf4j;

import org.apache.commons.codec.binary.Hex;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.*;

import static com.xiangban.xiangbanmall.utils.HttpUtils.sendPost;

/**
 * 工具类
 */
@Slf4j
@Component
public class CommonUtils {
    public static final String common_1="1";
    public static final String common_2="2";
    public static final String common_3="3";
    public static final String common_4="4";
    public static final String common_5="5";
    public static final String common_6="6";
    public static final Long DELAY_TIME = 1000*60*60L;
    public static final Long OVER_TIME = 1000*60*60L;
    public static final Long WAYBILL_TIME = 1000*60*60*24*7L;
    @Autowired
    private HttpServletRequest request;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private UserServiceFeign userServiceFeign;
    @Autowired
    private IdCardParameterConfig idCardParameterConfig;





    /**
     *     MD5加密工具
     * @param data
     * @return
     */

    public static String MD5(String data){
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] array = md.digest(data.getBytes("UTF-8"));
            StringBuilder stringBuilder = new StringBuilder();
            for (byte item: array) {
                stringBuilder.append(Integer.toHexString((item & 0xFF)| 0x100).substring(1,3));
            }
            return stringBuilder.toString().toUpperCase();
        }catch (Exception exception){
        }
        return null;
    }

    /**
     * java生成随机数字10位数
     *
     * @param length [生成随机数的长度]
     * @return
     */
    public static String getRandomNumber(int length) {
        String val = "";
        Random random = new Random();
        for (int i = 0; i < length; i++) {
            val += String.valueOf(random.nextInt(10));
        }
        return val;
    }

    /**
     * 生成 uuid， 即用来标识一笔单，也用做 nonce_str（微信支付）
     * @return
     */
    public static String generateUUID(int len){
        String uuid = UUID.randomUUID().toString().
                replaceAll("-","").substring(0,len);

        return uuid;
    }

    /**
     * 获取ip地址
     * @return
     */
    public static String getIpAddr(HttpServletRequest request) {
        String ipAddress = null;
        try {
            ipAddress = request.getHeader("x-forwarded-for");
            if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getHeader("Proxy-Client-IP");
            }
            if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getHeader("WL-Proxy-Client-IP");
            }
            if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getRemoteAddr();
                if (ipAddress.equals("127.0.0.1")) {
                    // 根据网卡取本机配置的IP
                    InetAddress inet = null;
                    try {
                        inet = InetAddress.getLocalHost();
                    } catch (UnknownHostException e) {
                        e.printStackTrace();
                    }
                    ipAddress = inet.getHostAddress();
                }
            }
            // 对于通过多个代理的情况，第一个IP为客户端真实IP,多个IP按照','分割
            if (ipAddress != null && ipAddress.length() > 15) { // "***.***.***.***".length()
                // = 15
                if (ipAddress.indexOf(",") > 0) {
                    ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));
                }
            }
        } catch (Exception e) {
            ipAddress="";
        }
        return ipAddress;
    }


    public static boolean BizEmpty(Object o){

        return o ==null || o.toString().length()<1;

    }
    public static boolean compare(String str1, String str2) {
        return str1.equals(str2);
    }

    /**
     * 校验用户合法性
     */
    public static void checkUserLegal(Object userId, HttpServletRequest request){
        RedisUtil redisUtil = new RedisUtil();
        if (!compare(redisUtil.get(userId.toString()), request.getHeader("token"))){
           throw new BizException(ApiResultCode.NOT_USER_ROLE_LEGAL);
       }
    }


    /**
     * 获取商家id
     */
    public  String getShopId(HttpServletRequest request){
        String token = RedisUtil.fex_shop + request.getHeader("token");
        String shopInfo = redisUtil.get(token);
        log.info("获取的token："+request.getHeader("token"));
        if (shopInfo.length()>0){
            Map<String,Object> parse = (Map<String, Object>) JSON.parse(shopInfo);
            return parse.get("shopId").toString();
        }
        return null;

    }

    public static String getHostIp(){
        String ip = "";
        try{
            ip = InetAddress.getLocalHost().getHostAddress();
        }catch(UnknownHostException e){
            e.printStackTrace();
        }
        return ip;
    }

    public static String getOrderNo(){
        return new SimpleDateFormat("yy-MM-dd-HH-mm-ss").format(new Date()).replace("-", "") + RandomStringUtils.randomNumeric(8);
    }
    public static String getSHA256Str(String str){
        MessageDigest messageDigest;
        String encdeStr = "";
        try {
            messageDigest = MessageDigest.getInstance("SHA-256");
            byte[] hash = messageDigest.digest(str.getBytes("UTF-8"));
            encdeStr = Hex.encodeHexString(hash);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return encdeStr;
    }

    public static String autoGenericCode(String code, int num) {
        String result = "";
        result = String.format("%0" + num + "d", Integer.parseInt(code) + 1);
        return result;
    }
    public String getWasteNumber(){
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat simpleDateFormatTime = new SimpleDateFormat("yyyyMMddHHmmss");
        String format = "Z"+simpleDateFormat.format(new Date());
        String formatTime = (simpleDateFormatTime.format(new Date())+new Date().getTime()+"").substring(0,25);
        //订单时间
        if (redisUtil.hasKey(format)){
            long incr = redisUtil.incr(format, 1);
            return "Z"+formatTime+autoGenericCode((incr-1) + "", 5);
        }else {
            redisUtil.set(format,"1",86400);
            return "Z"+formatTime+autoGenericCode("0", 5);
        }

    }
    public String getRefundWasteNumber(){
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat simpleDateFormatTime = new SimpleDateFormat("yyyyMMddHHmmss");
        String format = "T"+simpleDateFormat.format(new Date());
        String formatTime = (simpleDateFormatTime.format(new Date())+new Date().getTime()+"").substring(0,25);
        //订单时间
        if (redisUtil.hasKey(format)){
            long incr = redisUtil.incr(format, 1);
            return "T"+formatTime+autoGenericCode((incr-1) + "", 5);
        }else {
            redisUtil.set(format,"1",86400);
            return "T"+formatTime+autoGenericCode("0", 5);

        }

    }

    /**
     * scheduleId 课程ID
     * @return
     */
    public String getStudentCard(Integer scheduleId){
        String scheduleIdV = autoGenericCode((scheduleId - 1) + "", 4);
        String name = "CLASS_ID_"+scheduleIdV;
        //订单时间
        if (redisUtil.hasKey(name)){
            long incr = redisUtil.incr(name, 1);
            return "2109"+scheduleIdV+autoGenericCode((incr-1) + "", 4);
        }else {
            redisUtil.set(name,"1",86400);
            return "2109"+scheduleIdV+autoGenericCode("0", 4);

        }

    }

    /**
     * 获取用户id
     */
    public  String getUserId(HttpServletRequest request){
        try {
            return this.getUserIdByToken();
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }
    public  String getUserIdByToken() {
        request.getHeader("token");
        ApiResult<Object> res = userServiceFeign.getUserInfo("");
        Object dataMap = res.getDataMap();
        JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(dataMap));
        if (BizEmpty(dataMap)){
            return "";
        }
        return jsonObject.get("uid")+"";

    }

    /**
     * 校验身份证和姓名是否真实
     * @param idCard 身份证
     * @param name 姓名
     * @return
     * @throws Exception
     */
    public Boolean checkIdCard(String idCard, String name) throws Exception {
        Boolean flag = true;
        HashMap<String, String> params = new HashMap<>();
        HashMap<String, String> headers = new HashMap<>();
        params.put("idcard",idCard);
        params.put("name",name);
        headers.put("Authorization","APPCODE "+idCardParameterConfig.getRecognitionAppCode());
        String s = sendPost(idCardParameterConfig.getCheckUrl(), params, headers);
        String res = (String) JSON.parseObject(s).getJSONObject("result").get("res");
        String  description = (String) JSON.parseObject(s).getJSONObject("result").get("description");
        if (!res.equals("1") && !description.equals("一致")){
            flag = false;
        }
        return flag;
    }

    /**
     * 根据身份证计算年龄
     * @param idCard 身份证
     * @return 年龄
     */
    public int getAgeByIdCard(String idCard){
        Calendar cal = Calendar.getInstance();
        int yearNow = cal.get(Calendar.YEAR);
        int monthNow = cal.get(Calendar.MONTH)+1;
        int dayNow = cal.get(Calendar.DATE);

        int year = Integer.valueOf(idCard.substring(6, 10));
        int month = Integer.valueOf(idCard.substring(10,12));
        int day = Integer.valueOf(idCard.substring(12,14));

        if ((month < monthNow) || (month == monthNow && day<= dayNow) ){
            return yearNow - year;
        }else {
            return yearNow - year-1;
        }
    }

}
